{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第6章 日期函数的生成和转化\n",
    "\n",
    "不管在哪个领域中，时间序列（time series）数据都是一种重要的结构化数据形式。在多个时间点观察或测量到的任何事物都可以形成一段时间序列。很多时间序列是固定频率的，也就是说，数据点是根据某种规律定期出现的。时间序列也可以是不定期的。Pandas是在金融建模的背景下开发的，所以它包含了一套用于处理日期、时间和时间索引数据的工具。本章主要从以下几部分展开：\n",
    "\n",
    "一、日期和时间数据类型及工具\n",
    "* datatime模块\n",
    "* calendar模块\n",
    "* 字符串与datetime相互转换\n",
    "二、时间序列基础\n",
    "* 生成日期范围\n",
    "* 索引\n",
    "三、时区处理\n",
    "四、时期period及其算术运算\n",
    "五、日期的频率以及移动\n",
    "* 频率和偏移量\n",
    "* 时移shift\n",
    "六、重采样及频率转换\n",
    "* resample方法\n",
    "* 降采样\n",
    "* 升采样和插值\n",
    "七、移动窗囗函数\n",
    "八、指数加权函数"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from datetime import datetime\n",
    "from datetime import timedelta\n",
    "from datetime import date\n",
    "from datetime import time\n",
    "import calendar"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 一、日期和时间数据类型及工具\n",
    "Python标准库包含用于日期（date）和时间（time）数据的数据类型，而且还有日历方面的功能。\n",
    "datetime.datetime是用得最多的数据类型。我们主要介绍datetime模块、calendar模块以及字符串与datetime的转化。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## datetime 模块\n",
    "datetime 模块提供了可以通过多种方式操作日期和时间的类"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "datetime中的数据类型\n",
    "date:以公历形式存储日历日期\n",
    "time：以时间存储为时，分，秒，毫秒\n",
    "datetime：存储日期和时间\n",
    "timedelta：表示两个datetime之间的差（日，秒，毫秒）"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### date"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "class datetime.date(year, month, day)\n",
    "date.year年\n",
    "date.month月\n",
    "date.day日\n",
    "date.replace(year[, month[, day]])生成并返回一个新的日期对象，原日期对象不变\n",
    "date.timetuple()返回日期对应的time.struct_time对象\n",
    "date.toordinal()返回日期是是自 0001-01-01 开始的第多少天\n",
    "date.weekday()返回日期是星期几，[0, 6]，0表示星期一\n",
    "date.isoweekday()返回日期是星期几，[1, 7], 1表示星期一\n",
    "date.isocalendar()返回一个元组，格式为：(year, weekday, isoweekday)\n",
    "date.isoformat()返回‘YYYY-MM-DD’格式的日期字符串\n",
    "date.strftime(format)返回指定格式的日期字符串"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "date对象所能表示的最大日期 9999-12-31\n",
      "date对象所能表示的最小日期 0001-01-01\n",
      "今天是： 2019-08-20\n",
      "生成一个新的日期对象，更改年： 2016-08-20\n",
      "生成一个新的日期对象，更改年月： 2016-03-20\n",
      "生成一个新的日期对象，更改年月日： 2016-03-02\n",
      "日期对应的time.struct_time对象：\n",
      " time.struct_time(tm_year=2019, tm_mon=8, tm_mday=20, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=1, tm_yday=232, tm_isdst=-1)\n",
      "自 0001-01-01 开始的第 737291 天\n",
      "(0表示星期一)星期 1\n",
      "(1表示星期一)星期 2\n",
      "格式为：(year, weekday, isoweekday)的元组： (2019, 34, 2)\n",
      "‘YYYY-MM-DD’格式的日期字符串： 2019-08-20\n",
      "date对象所能表示的最大日期 Tue Aug 20 00:00:00 2019\n",
      "指定格式的日期字符串： 2019/08/20\n"
     ]
    }
   ],
   "source": [
    "print(\"date对象所能表示的最大日期\",date.max)\n",
    "print(\"date对象所能表示的最小日期\",date.min)\n",
    "d = date.today()\n",
    "print(\"今天是：\",d)\n",
    "print(\"生成一个新的日期对象，更改年：\",d.replace(2016))\n",
    "print(\"生成一个新的日期对象，更改年月：\",d.replace(2016, 3))\n",
    "print(\"生成一个新的日期对象，更改年月日：\",d.replace(2016, 3, 2))\n",
    "print(\"日期对应的time.struct_time对象：\\n\",d.timetuple())\n",
    "print(\"自 0001-01-01 开始的第\",d.toordinal(),\"天\")\n",
    "print(\"(0表示星期一)星期\",d.weekday())\n",
    "print(\"(1表示星期一)星期\",d.isoweekday())\n",
    "print(\"格式为：(year, weekday, isoweekday)的元组：\",d.isocalendar())\n",
    "print(\"‘YYYY-MM-DD’格式的日期字符串：\",d.isoformat())\n",
    "print(\"date对象所能表示的最大日期\",d.ctime())\n",
    "print(\"指定格式的日期字符串：\",d.strftime('%Y/%m/%d'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### time"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "class datetime.time(hour,minute,second,microsecond,tzinfo)\n",
    "time.max   time类所能表示的最大时间：time(23, 59, 59, 999999)\n",
    "time.min   time类所能表示的最小时间：time(0, 0, 0, 0)\n",
    "time.resolution  时间的最小单位，即两个不同时间的最小差值：1微秒\n",
    "t.replace(hour,minute,second,microsecond,tzinfo)\t生成并返回一个新的时间对象，原时间对象不变\n",
    "t.isoformat()\t返回一个‘HH:MM:SS.%f’格式的时间字符串\n",
    "t.strftime()\t返回指定格式的时间字符串，与time模块的strftime(format, struct_time)功能相同"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "time类所能表示的最大时间: 23:59:59.999999\n",
      "time类所能表示的最小时间: 00:00:00\n",
      "时间的最小单位: 0:00:00.000001\n",
      "(时，分，秒，微秒，tzinfo)： 20 5 40 8888 None\n",
      "生成新的时间对象，代替时 21:05:40.008888\n",
      "HH:MM:SS.%f’格式的时间字符串 20:05:40.008888\n",
      "返回指定格式的时间字符串 200540\n"
     ]
    }
   ],
   "source": [
    "print(\"time类所能表示的最大时间:\",time.max)\n",
    "print(\"time类所能表示的最小时间:\",time.min)\n",
    "print(\"时间的最小单位:\",time.resolution)\n",
    "t = time(20, 5, 40, 8888)\n",
    "print(\"(时，分，秒，微秒，tzinfo)：\",t.hour,t.minute,t.second,t.microsecond,t.tzinfo)\n",
    "print(\"生成新的时间对象，代替时\",t.replace(21))\n",
    "print(\"HH:MM:SS.%f’格式的时间字符串\",t.isoformat())\n",
    "print(\"返回指定格式的时间字符串\",t.strftime('%H%M%S'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### datetime"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "class datetime.datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None)\n",
    "datetime.today()返回一个表示当前本期日期时间的datetime对象\n",
    "datetime.now([tz])返回指定时区日期时间的datetime对象，如果不指定tz参数则结果同上\n",
    "datetime.utcnow()返回当前utc日期时间的datetime对象\n",
    "datetime.strftime(date_str, format)将datetime对象转换为时间字符串\n",
    "datetime.strptime(date_str, format)将时间字符串转换为datetime对象"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "属性：year,month,day,hour,minute,second,microsecond,tzinfo.\n",
      "      2019 8 20 12 43 7 246369 None\n",
      "2019-08-20 12:43:07.246369\n",
      "2019-08-20 04:43:07.246369\n",
      "2019-08-20T12:43:07.246369\n",
      "2019-08-20\n",
      "2019-08-19 20:49:00\n"
     ]
    }
   ],
   "source": [
    "now = datetime.now()\n",
    "print(\"属性：year,month,day,hour,minute,second,microsecond,tzinfo.\")\n",
    "print(\"     \",now.year,now.month,now.day,now.hour,now.minute,now.second,now.microsecond,now.tzinfo)\n",
    "print(datetime.today())\n",
    "print(datetime.utcnow())\n",
    "print(now.isoformat())#返回一个 ISO 8601 格式的字符串， 'YYYY-MM-DD'。\n",
    "print(now.strftime('%Y-%m-%d'))#接收一个时间元组，并返回以可读字符串表示的当地时间，格式由参数决定。\n",
    "print(datetime.strptime('2019/08/19 20:49', '%Y/%m/%d %H:%M'))#将字符串转为datetime"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### timedelta"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "如果有人问你昨天是几号，这个很容易就回答出来了。但是如果问你200天前是几号，就不是那么容易答出来。而在Python中datetime模块中的timedelta就可以很轻松给出答案。 timedelta 对象表示两个 date 或者 time 的时间间隔。\n",
    "class datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, hours=0, weeks=0)\n",
    "datetime.datetime.now()\t返回当前本地时间（datetime.datetime对象实例）\n",
    "datetime.datetime.fromtimestamp(timestamp)\t返回指定时间戳对应的时间（datetime.datetime对象实例）\n",
    "datetime.timedelta()\t返回一个时间间隔对象，可以直接与datetime.datetime对象做加减操作"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "一年包含的总秒数: 31536000.0\n",
      "3天后: 2019-08-23 12:43:07.327154\n",
      "3天前: 2019-08-17 12:43:07.327154\n",
      "3小时后: 2019-08-20 15:43:07.327154\n",
      "3小时前: 2019-08-20 09:43:07.327154\n",
      "3小时30秒后: 2019-08-20 15:43:37.327154\n"
     ]
    }
   ],
   "source": [
    "print(\"一年包含的总秒数:\",timedelta(365).total_seconds())\n",
    "dt = datetime.now()\n",
    "print(\"3天后:\",dt + timedelta(3))\n",
    "print(\"3天前:\",dt + timedelta(-3))\n",
    "print(\"3小时后:\",dt + timedelta(hours=3))\n",
    "print(\"3小时前:\",dt + timedelta(hours=-3))\n",
    "print(\"3小时30秒后:\",dt + timedelta(hours=3, seconds=30))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## calendar模块\n",
    "calendar是与日历相关的模块，calendar模块文件里定义了很多类型，主要有Calendar，TextCalendar以及HTMLCalendar类型。其中，Calendar是TextCalendar与HTMLCalendar的基类。该模块文件还对外提供了很多方法，例如：calendar，month，prcal，prmonth之类的方法。"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "calendar模块方法\n",
    "calendar.setfirstweekday(firstweekday)指定一周的第一天，0是星期一，…，6为星期日\n",
    "calendar.firstweekday()返回一周的第一天，0是星期一，…，6为星期日\n",
    "calendar.isleap(year)：判断指定是否是闰年，闰年为True，平年为False\n",
    "calendar.leapdays(y1, y2)：返回y1与y2年份之间的闰年数量，y1与y2皆为年份。包括起始年，不包括结束年：\n",
    "calendar.weekday(year, month, day)：获取指定日期为星期几\n",
    "calendar.weekheader(n)：返回包含星期的英文缩写，n表示英文缩写所占的宽度\n",
    "calendar.monthrange(year, month)：返回一个由一个月第一个天的星期与当前月的天数组成的元组\n",
    "calendar.monthcalendar(year, month)：返回一个月中天数列表(不是当前月份的天数为0)，按周划分，为一个二维数组。包括月份开始那周的所有日期和月份结束那周的所有日期\n",
    "calendar.prmonth(year,month, w=0, l=0)：打印一个月的日历\n",
    "calendar.month(year,month, w=0, l=0)：返回一个月的日历的多行文本字符串。\n",
    "calendar.prcal(year, w=0, l=0, c=6, m=3)：打印一年的日历，\n",
    "calendar.calendar(year, w=2, l=1, c=6, m=3)：以多行字符串形式返回一年的日历\n",
    "参数说明：\n",
    "w:每个单元格宽度，默认0，内部已做处理，最小宽度为2\n",
    "l:每列换l行，默认为0，内部已做处理，至少换行1行\n",
    "c:表示月与月之间的间隔宽度，默认为6，内部已做处理，最小宽度为2\n",
    "m:表示将12个月分为m列"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "6\n",
      "False\n",
      "2008年到2019年之间闰年数量： 3\n",
      "2019-8-8是星期： 3\n",
      "包含星期的英文缩写: Sun  Mon  Tue  Wed  Thu  Fri  Sat \n",
      "2019年8月天数列表: [[0, 0, 0, 0, 1, 2, 3], [4, 5, 6, 7, 8, 9, 10], [11, 12, 13, 14, 15, 16, 17], [18, 19, 20, 21, 22, 23, 24], [25, 26, 27, 28, 29, 30, 31]]\n",
      "    August 2019\n",
      "Su Mo Tu We Th Fr Sa\n",
      "             1  2  3\n",
      " 4  5  6  7  8  9 10\n",
      "11 12 13 14 15 16 17\n",
      "18 19 20 21 22 23 24\n",
      "25 26 27 28 29 30 31\n",
      "2019年8月的日历: None\n",
      "2019年8月的日历的多行文本字符串:\n",
      "     August 2019\n",
      "Su Mo Tu We Th Fr Sa\n",
      "             1  2  3\n",
      " 4  5  6  7  8  9 10\n",
      "11 12 13 14 15 16 17\n",
      "18 19 20 21 22 23 24\n",
      "25 26 27 28 29 30 31\n",
      "\n",
      "                                               2019\n",
      "\n",
      "      January                   February                   March                     April\n",
      "Su Mo Tu We Th Fr Sa      Su Mo Tu We Th Fr Sa      Su Mo Tu We Th Fr Sa      Su Mo Tu We Th Fr Sa\n",
      "       1  2  3  4  5                      1  2                      1  2          1  2  3  4  5  6\n",
      " 6  7  8  9 10 11 12       3  4  5  6  7  8  9       3  4  5  6  7  8  9       7  8  9 10 11 12 13\n",
      "13 14 15 16 17 18 19      10 11 12 13 14 15 16      10 11 12 13 14 15 16      14 15 16 17 18 19 20\n",
      "20 21 22 23 24 25 26      17 18 19 20 21 22 23      17 18 19 20 21 22 23      21 22 23 24 25 26 27\n",
      "27 28 29 30 31            24 25 26 27 28            24 25 26 27 28 29 30      28 29 30\n",
      "                                                    31\n",
      "\n",
      "        May                       June                      July                     August\n",
      "Su Mo Tu We Th Fr Sa      Su Mo Tu We Th Fr Sa      Su Mo Tu We Th Fr Sa      Su Mo Tu We Th Fr Sa\n",
      "          1  2  3  4                         1          1  2  3  4  5  6                   1  2  3\n",
      " 5  6  7  8  9 10 11       2  3  4  5  6  7  8       7  8  9 10 11 12 13       4  5  6  7  8  9 10\n",
      "12 13 14 15 16 17 18       9 10 11 12 13 14 15      14 15 16 17 18 19 20      11 12 13 14 15 16 17\n",
      "19 20 21 22 23 24 25      16 17 18 19 20 21 22      21 22 23 24 25 26 27      18 19 20 21 22 23 24\n",
      "26 27 28 29 30 31         23 24 25 26 27 28 29      28 29 30 31               25 26 27 28 29 30 31\n",
      "                          30\n",
      "\n",
      "     September                  October                   November                  December\n",
      "Su Mo Tu We Th Fr Sa      Su Mo Tu We Th Fr Sa      Su Mo Tu We Th Fr Sa      Su Mo Tu We Th Fr Sa\n",
      " 1  2  3  4  5  6  7             1  2  3  4  5                      1  2       1  2  3  4  5  6  7\n",
      " 8  9 10 11 12 13 14       6  7  8  9 10 11 12       3  4  5  6  7  8  9       8  9 10 11 12 13 14\n",
      "15 16 17 18 19 20 21      13 14 15 16 17 18 19      10 11 12 13 14 15 16      15 16 17 18 19 20 21\n",
      "22 23 24 25 26 27 28      20 21 22 23 24 25 26      17 18 19 20 21 22 23      22 23 24 25 26 27 28\n",
      "29 30                     27 28 29 30 31            24 25 26 27 28 29 30      29 30 31\n",
      "\n",
      "2019年的日历: None\n",
      "2019年的日历的多行文本字符串:\n",
      "                                                2018\n",
      "\n",
      "      January                   February                   March                     April\n",
      "Su Mo Tu We Th Fr Sa      Su Mo Tu We Th Fr Sa      Su Mo Tu We Th Fr Sa      Su Mo Tu We Th Fr Sa\n",
      "    1  2  3  4  5  6                   1  2  3                   1  2  3       1  2  3  4  5  6  7\n",
      " 7  8  9 10 11 12 13       4  5  6  7  8  9 10       4  5  6  7  8  9 10       8  9 10 11 12 13 14\n",
      "14 15 16 17 18 19 20      11 12 13 14 15 16 17      11 12 13 14 15 16 17      15 16 17 18 19 20 21\n",
      "21 22 23 24 25 26 27      18 19 20 21 22 23 24      18 19 20 21 22 23 24      22 23 24 25 26 27 28\n",
      "28 29 30 31               25 26 27 28               25 26 27 28 29 30 31      29 30\n",
      "\n",
      "        May                       June                      July                     August\n",
      "Su Mo Tu We Th Fr Sa      Su Mo Tu We Th Fr Sa      Su Mo Tu We Th Fr Sa      Su Mo Tu We Th Fr Sa\n",
      "       1  2  3  4  5                      1  2       1  2  3  4  5  6  7                1  2  3  4\n",
      " 6  7  8  9 10 11 12       3  4  5  6  7  8  9       8  9 10 11 12 13 14       5  6  7  8  9 10 11\n",
      "13 14 15 16 17 18 19      10 11 12 13 14 15 16      15 16 17 18 19 20 21      12 13 14 15 16 17 18\n",
      "20 21 22 23 24 25 26      17 18 19 20 21 22 23      22 23 24 25 26 27 28      19 20 21 22 23 24 25\n",
      "27 28 29 30 31            24 25 26 27 28 29 30      29 30 31                  26 27 28 29 30 31\n",
      "\n",
      "     September                  October                   November                  December\n",
      "Su Mo Tu We Th Fr Sa      Su Mo Tu We Th Fr Sa      Su Mo Tu We Th Fr Sa      Su Mo Tu We Th Fr Sa\n",
      "                   1          1  2  3  4  5  6                   1  2  3                         1\n",
      " 2  3  4  5  6  7  8       7  8  9 10 11 12 13       4  5  6  7  8  9 10       2  3  4  5  6  7  8\n",
      " 9 10 11 12 13 14 15      14 15 16 17 18 19 20      11 12 13 14 15 16 17       9 10 11 12 13 14 15\n",
      "16 17 18 19 20 21 22      21 22 23 24 25 26 27      18 19 20 21 22 23 24      16 17 18 19 20 21 22\n",
      "23 24 25 26 27 28 29      28 29 30 31               25 26 27 28 29 30         23 24 25 26 27 28 29\n",
      "30                                                                            30 31\n",
      "\n"
     ]
    }
   ],
   "source": [
    "calendar.setfirstweekday(firstweekday=6)\n",
    "print(calendar.firstweekday())\n",
    "print(calendar.isleap(2019))\n",
    "print(\"2008年到2019年之间闰年数量：\",calendar.leapdays(2008, 2019))\n",
    "print(\"2019-8-8是星期：\",calendar.weekday(2019, 8, 8))# 2019-08-08正是星期四，千万别忘记3代表的是星期四\n",
    "print(\"包含星期的英文缩写:\",calendar.weekheader(4))\n",
    "print(\"2019年8月天数列表:\",calendar.monthcalendar(2019, 8))\n",
    "print(\"2019年8月的日历:\",calendar.prmonth(2019,8))\n",
    "print(\"2019年8月的日历的多行文本字符串:\\n\",calendar.month(2019, 8))\n",
    "print(\"2019年的日历:\",calendar.prcal(2019, m=4))\n",
    "print(\"2019年的日历的多行文本字符串:\\n\",calendar.calendar(2018, m=4))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  字符串与datetime的相互转换"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "datetime格式定义：\n",
    "\n",
    "%Y:4位数的年\n",
    "%y:2位数的年\n",
    "%m:2位数的月[01,12]\n",
    "%d:2位数的日[01,31]\n",
    "%H:23小时制[00,23]\n",
    "%I:12小时制[01,12]\n",
    "%M:2位数的分[00,59]\n",
    "%S:秒[00,61]秒60和61用于闰秒\n",
    "%w:用整数表示的星期几[0(星期日),6]\n",
    "%U:每年的第几周[00,53]。星期天被认为是每周的第一天，每年的第一个星期天之前的几天是第0周\n",
    "%W:每年的第几周[00,53]。星期一被认为是每周的第一天，每年的第一个星期一之前的几天是第0周\n",
    "%z:以+HHMM或-HHMM表示的UTC时间对象，如果时区为naive，则返回空字符串\n",
    "%F: %Y-%m-%d简写形式，例如2012-04-18\n",
    "%D:%m%d%y简写形式，例如04/18/12\n",
    "\n",
    "特定于当年环境的日期格式：\n",
    "\n",
    "%a：星期几的简写%A星期几的全称\n",
    "%b：月份的简写%B月份的全称\n",
    "%c：完整的日期和时间，例如“Tue 01May 201204：20：57PM”\n",
    "%p：不同环境中的AM或PM\n",
    "%x：适合于当前环境的日期格式，例如，在美国，“May 1，2019”会产生“05/01/2019”\n",
    "%X：适合于当前环境的时间格式，例如“04：24：12PM”\n",
    "\n",
    "利用str或strftime方法（传入一个格式化字符串），datetime对象和pandas的Timestamp对象（稍后就会介绍）可以被格式化为字符串："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('2019-07-03 00:00:00', '2019-07-03')"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "stamp=datetime(2019,7,3)\n",
    "str(stamp),stamp.strftime('%Y-%m-%d')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(datetime.datetime(2019, 1, 3, 0, 0), datetime.datetime(2011, 12, 6, 0, 0))"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#对于一些常见的日期格式每次要编写格式定义是很麻烦的事情，这种情况下，可以用dateutil这个第三方包中的parser.parse方法：\n",
    "from dateutil.parser import parse\n",
    "parse('2019-01-03'),parse('6/12/2011',dayfirst=True)#日期在前，dayfirst=True"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "Pandas提供Timestamp类型为时间戳。关联的索引结构是DatetimeIndex.\n",
    "Pandas提供Period类型为时间段。这将编码一个固定频率间隔，该间隔基于numpy.datetime64..关联的索引结构是PeriodIndex.\n",
    "Pandas提供Timedelta类型为时间三角洲或持续时间。Timedelta是Python本机更有效的替代品datetime.timedelta类型，关联的索引结构是TimedeltaIndex.\n",
    "\n",
    "这些日期/时间对象中最基本的是Timestamp和DatetimeIndex。虽然可以直接调用这些类对象，但使用pd.to_datetime()函数可以解析多种格式。将一个日期传递给pd.to_datetime()产生一个Timestamp；默认情况下传递一系列日期将产生DatetimeIndex"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2015-07-04 00:00:00')"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#在pandas中可以使用to_datetime方法处理成组日期,解析多种不同的日期表现形式\n",
    "date = pd.to_datetime(\"4th of July, 2015\")\n",
    "date"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2015-07-04', '2015-07-05', '2015-07-06', '2015-07-07',\n",
       "               '2015-07-08', '2015-07-09', '2015-07-10', '2015-07-11',\n",
       "               '2015-07-12', '2015-07-13', '2015-07-14', '2015-07-15'],\n",
       "              dtype='datetime64[ns]', freq=None)"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#此外，我们可以直接对同一个对象执行NumPy风格的矢量化操作：\n",
    "date + pd.to_timedelta(np.arange(12), 'D')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2014-07-04    0\n",
       "2014-08-04    1\n",
       "2015-07-04    2\n",
       "2015-08-04    3\n",
       "dtype: int64"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#构造一个具有时间索引数据的Series\n",
    "index = pd.DatetimeIndex(['2014-07-04', '2014-08-04',\n",
    "                          '2015-07-04', '2015-08-04'])\n",
    "data = pd.Series([0, 1, 2, 3], index=index)\n",
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2015-07-03', '2015-07-04', '2015-07-06', '2015-07-07',\n",
       "               '2015-07-08'],\n",
       "              dtype='datetime64[ns]', freq=None)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dates = pd.to_datetime([datetime(2015, 7, 3), '4th of July, 2015',\n",
    "                       '2015-Jul-6', '07-07-2015', '20150708'])\n",
    "dates"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PeriodIndex(['2015-07-03', '2015-07-04', '2015-07-06', '2015-07-07',\n",
       "             '2015-07-08'],\n",
       "            dtype='period[D]', freq='D')"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#任何DatetimeIndex可以转换为PeriodIndex:to_period()函数,使用'D'指示每日频率：\n",
    "dates.to_period('D')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "TimedeltaIndex(['0 days', '1 days', '3 days', '4 days', '5 days'], dtype='timedelta64[ns]', freq=None)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#当从另一个日期减去日期时,生成一个TimedeltaIndex\n",
    "dates - dates[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 二、时间序列基础\n",
    "当数据是以时间戳作为索引的话，可以将其理解为一个时间序列数据。我们主要介绍生成日期范围与时间序列的索引。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 生成日期范围"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "pd.date_range(start,end,periods)\n",
    "为了更方便地创建日期序列，Pandas为此提供了一些功能：pd.date_range()时间戳，pd.period_range()一段时间内，以及pd.timedelta_range()。\n",
    "我们都知道，Python的range()和NumPy的np.arange()将起始点、端点和可选步长转换为序列。同样，pd.date_range()接受开始日期、结束日期和可选频率代码，以创建定期日期序列。默认情况下，频率为某一天。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2000-01-01    1.315127\n",
       "2000-01-02    2.128896\n",
       "2000-01-03    0.927003\n",
       "2000-01-04   -0.880661\n",
       "2000-01-05   -1.547260\n",
       "Freq: D, dtype: float64"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "long_ts = pd.Series(np.random.randn(1000),index=pd.date_range('1/1/2000',periods=1000))\n",
    "long_ts.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 索引"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2002-09-24   -0.627696\n",
      "2002-09-25   -1.633077\n",
      "2002-09-26    1.457194\n",
      "Freq: D, dtype: float64\n",
      "2002-09-24   -0.627696\n",
      "2002-09-25   -1.633077\n",
      "2002-09-26    1.457194\n",
      "Freq: D, dtype: float64\n"
     ]
    }
   ],
   "source": [
    "#索引,两种方式结果一样\n",
    "print(long_ts['2002-9-24':])\n",
    "print(long_ts[datetime(2002,9,24):])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2002-09-01   -0.435344\n",
       "2002-09-02   -0.448500\n",
       "2002-09-03    0.908174\n",
       "2002-09-04    1.399495\n",
       "2002-09-05   -1.199545\n",
       "2002-09-06    0.980850\n",
       "2002-09-07   -2.008823\n",
       "2002-09-08   -0.527086\n",
       "2002-09-09    0.788963\n",
       "2002-09-10   -1.606466\n",
       "2002-09-11   -0.083876\n",
       "2002-09-12   -1.248117\n",
       "2002-09-13    0.288755\n",
       "2002-09-14   -0.293276\n",
       "2002-09-15   -0.510468\n",
       "2002-09-16    1.001119\n",
       "2002-09-17    1.386802\n",
       "2002-09-18   -0.667894\n",
       "2002-09-19   -1.245537\n",
       "2002-09-20    0.024803\n",
       "2002-09-21    0.307759\n",
       "2002-09-22   -1.018092\n",
       "2002-09-23   -1.237862\n",
       "2002-09-24   -0.627696\n",
       "2002-09-25   -1.633077\n",
       "2002-09-26    1.457194\n",
       "Freq: D, dtype: float64"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "long_ts['2002-09']#选取2001-05的数据"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 带有重复索引的时间序列 即一个时间出现多条记录"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2000-01-01    0\n",
       "2000-01-02    1\n",
       "2000-01-02    2\n",
       "2000-01-02    3\n",
       "2000-01-03    4\n",
       "dtype: int32"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dates = pd.DatetimeIndex(['1/1/2000','1/2/2000','1/2/2000','1/2/2000','1/3/2000'])\n",
    "dup_ts = pd.Series(np.arange(5),index=dates)\n",
    "dup_ts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#检查索引是否唯一\n",
    "dup_ts.index.is_unique"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2000-01-01    1\n",
       "2000-01-02    3\n",
       "2000-01-03    1\n",
       "dtype: int64"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#通过groupby检查\n",
    "dup_ts.groupby(level=0).count()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 三、时区处理"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "时间序列处理工作中最麻烦的是对时区的处理。尤其是夏令时（DST）转变，这是一种最常见的麻烦事，就这一点来说，许多人都选择以协调世界时（UTC）来处理时间序列。时区是以UTC偏移量的形式表示的。例如，夏令时期间，纽约比UTC慢4小时，而在全年其他时间则比UTC慢5小时。\n",
    "\n",
    "在Python中，时区信息来自第三方库pytz，它使Python可以使用Olson数据库。这对历史数据非常重要，这是因为由于各地政府的各种突发奇想，夏令时转变日期（甚至UTC偏移量）已经发生过多次改变了。就拿美国来说，DST转变时间自1900年以来就改变过多次。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['US/Eastern', 'US/Hawaii', 'US/Mountain', 'US/Pacific', 'UTC']"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#由于pandas包装了pytz的功能，因此你可以不用记忆其API，只要记得时区的名称即可。时区名可以在文档中找到，也可以通过交互的方式查看：\n",
    "import pytz\n",
    "pytz.common_timezones[-5:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<DstTzInfo 'US/Eastern' LMT-1 day, 19:04:00 STD>"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#要从pytz中获取时区对象，使用pytz.timezone即可：\n",
    "tz=pytz.timezone(\"US/Eastern\")\n",
    "tz"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 本地化和转换\n",
    "默认情况下，pandas中的时间序列是单纯的（naive）时区"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "tz_localize()时区定位/本地化\n",
    "tz_convert()时区转换"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "None\n"
     ]
    }
   ],
   "source": [
    "rng=pd.date_range('3/9/2012 9:30',periods=6,freq='D')\n",
    "ts=pd.Series(np.random.randn(len(rng)),index=rng)\n",
    "print(ts.index.tz)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2012-03-09 09:30:00+00:00', '2012-03-10 09:30:00+00:00',\n",
       "               '2012-03-11 09:30:00+00:00', '2012-03-12 09:30:00+00:00',\n",
       "               '2012-03-13 09:30:00+00:00', '2012-03-14 09:30:00+00:00',\n",
       "               '2012-03-15 09:30:00+00:00', '2012-03-16 09:30:00+00:00',\n",
       "               '2012-03-17 09:30:00+00:00', '2012-03-18 09:30:00+00:00'],\n",
       "              dtype='datetime64[ns, UTC]', freq='D')"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#在生成日期范围的时候还可以加上一个时区集\n",
    "pd.date_range('3/9/2012 9:30',periods=10,freq='D',tz='UTC')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2012-03-09 09:30:00+00:00    0.525350\n",
       "2012-03-10 09:30:00+00:00    0.498384\n",
       "2012-03-11 09:30:00+00:00   -1.603312\n",
       "2012-03-12 09:30:00+00:00    0.368390\n",
       "2012-03-13 09:30:00+00:00    1.245520\n",
       "2012-03-14 09:30:00+00:00    2.336125\n",
       "Freq: D, dtype: float64"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#从单纯到本地化的转换是通过tz_localize方法处理的：\n",
    "ts_utc=ts.tz_localize('UTC')\n",
    "ts_utc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2012-03-09 09:30:00+00:00', '2012-03-10 09:30:00+00:00',\n",
       "               '2012-03-11 09:30:00+00:00', '2012-03-12 09:30:00+00:00',\n",
       "               '2012-03-13 09:30:00+00:00', '2012-03-14 09:30:00+00:00'],\n",
       "              dtype='datetime64[ns, UTC]', freq='D')"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts_utc.index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2012-03-09 04:30:00-05:00    0.525350\n",
       "2012-03-10 04:30:00-05:00    0.498384\n",
       "2012-03-11 05:30:00-04:00   -1.603312\n",
       "2012-03-12 05:30:00-04:00    0.368390\n",
       "2012-03-13 05:30:00-04:00    1.245520\n",
       "2012-03-14 05:30:00-04:00    2.336125\n",
       "Freq: D, dtype: float64"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#一旦时间序列被本地化到某个特定时区，就可以用tz_convert将其转换到别的时区了：\n",
    "ts_utc.tz_convert('US/Eastern')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2012-03-09 14:30:00+00:00    0.525350\n",
       "2012-03-10 14:30:00+00:00    0.498384\n",
       "2012-03-11 13:30:00+00:00   -1.603312\n",
       "2012-03-12 13:30:00+00:00    0.368390\n",
       "2012-03-13 13:30:00+00:00    1.245520\n",
       "2012-03-14 13:30:00+00:00    2.336125\n",
       "Freq: D, dtype: float64"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#对于上面这种时间序列（它跨越了美国东部时区的夏令时转变期），我们可以将其本地化到EST，然后转换为UTC或柏林时间：\n",
    "ts_eastern=ts.tz_localize('US/Eastern')\n",
    "ts_eastern.tz_convert('UTC')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2012-03-09 09:30:00+08:00', '2012-03-10 09:30:00+08:00',\n",
       "               '2012-03-11 09:30:00+08:00', '2012-03-12 09:30:00+08:00',\n",
       "               '2012-03-13 09:30:00+08:00', '2012-03-14 09:30:00+08:00'],\n",
       "              dtype='datetime64[ns, Asia/Shanghai]', freq='D')"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#tz_1ocalize和tz_convert也是DatetimeIndex的实例方法\n",
    "ts.index.tz_localize('Asia/Shanghai')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 四、时期period及其算术运算\n",
    "时期（period）表示的是时间区间，比如数日、数月、数季、数年等。 Period类所表示的就是这种数据类型，其构造函数需要用到一个字符串或整数和频率。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Period('2007', 'A-DEC')"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p=pd.Period(2007,freq='A-DEC')#这个Period对象表示的是从2007年1月1日到2007年12月31日之间的整段时间。\n",
    "p"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(Period('2012', 'A-DEC'), Period('2005', 'A-DEC'))"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#对Period对象加上或减去一个整数即可达到根据其频率进行位移的效果：\n",
    "p+5,p-2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PeriodIndex(['2000-01', '2000-02', '2000-03', '2000-04', '2000-05', '2000-06'], dtype='period[M]', freq='M')"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#period_range函数可用于创建规则的时期范围：\n",
    "rng=pd.period_range('1/1/2000','6/30/2000',freq='M')\n",
    "rng"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2000-01   -0.165660\n",
       "2000-02   -0.146480\n",
       "2000-03    0.287034\n",
       "2000-04    0.767443\n",
       "2000-05   -0.084857\n",
       "2000-06    1.513086\n",
       "Freq: M, dtype: float64"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#PeriodIndex类保存了一组Period，它可以在任何pandas数据结构中被用作轴索引：\n",
    "pd.Series(np.random.randn(6),index=rng)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PeriodIndex(['2003Q1', '2002Q1', '2001Q1'], dtype='period[Q-DEC]', freq='Q-DEC')"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#PeriodIndex类的构造函数还允许直接使用一组字符串\n",
    "values=['200103','200202','200301']\n",
    "index=pd.PeriodIndex(values,freq='Q-DEC')\n",
    "index"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 五、日期的频率以及移动\n",
    "pandas中的时间序列一般被认为是不规则的，也就是说，它们没有固定的频率。对于大部分应用程序而言，这是无所谓的。但是，它常常需要以某种相对固定的频率进行分析，比如每日、每月、每15分钟等（这样自然会在时间序列中引入缺失值）。幸运的是，pandas有一整套标准时间序列频率以及用于重采样、频率推断、生成固定频率日期范围的工具。我们主要介绍频率和偏移量以及时移。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 频率和偏移量"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "Pandas时间序列工具的基础是频率或日期偏移的概念。\n",
    "pandas中的频率是由一个基础频率（base frequency）和一个乘数组成的。基础频率通常以一个字符串别名表示，比如“M”表示每月，“H”表示每小时。对于每个基础频率，都有一个被称为日期偏移量（date offset）的对象与之对应。\n",
    "有些频率所描述的时间点并不是均匀分隔的。例如，“M”（日历月末）和“BM”（每月最后一个工作日）就取决于每月的天数，对于后者，还要考虑月末是不是周末。由于没有更好的术语，我将这些称为锚点偏移量（anchored offset）。\n",
    "时间序列的基础频率：\n",
    "D\t日历日\t\n",
    "W\t每周\t\t\n",
    "M\t月底\t\n",
    "Q\t季度末\t\n",
    "A\t年底\t\n",
    "H\t小时数\t\n",
    "T\t分分钟\t\t\n",
    "S\t秒数\t\t\n",
    "L\t米利斯秒\t\t\n",
    "U\t微秒\t\t\n",
    "N\t纳秒\n",
    "B\t营业日\n",
    "BM\t营业月结束\n",
    "BQ\t营业季度末\n",
    "BA\t营业年度结束\n",
    "BH\t营业时间\n",
    "\n",
    "每个月、每个季度和每年的频率都是在指定期间结束时标记的。通过添加S它们的后缀将在开头标记：\n",
    "MS\t月开始\t\t\n",
    "QS\t季度启动\t\t\n",
    "AS\t年初\t\t\n",
    "BMS\t营业月开始\n",
    "BQS\t营业季度开始\n",
    "BAS\t营业年度开始\n",
    "\n",
    "此外，还可以通过添加三个字母的月份代码作为后缀来更改用于标记任何季度或年度代码的月份：\n",
    "Q-JAN, BQ-FEB, QS-MAR, BQS-APR等\n",
    "\n",
    "同样，可以通过添加三个字母的工作日代码来修改每周频率的分割点：\n",
    "W-SUN, W-MON, W-TUE, W-WED等\n",
    "\n",
    "最重要的是，它们可以与数字相结合来指定其他频率。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "TimedeltaIndex(['00:00:00', '02:30:00', '05:00:00', '07:30:00', '10:00:00',\n",
       "                '12:30:00', '15:00:00', '17:30:00', '20:00:00'],\n",
       "               dtype='timedelta64[ns]', freq='150T')"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#例如，在频率为2小时30分钟的情况下，我们可以将该小时(H)和分钟(T)守则如下：\n",
    "pd.timedelta_range(0, periods=9, freq=\"2H30T\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2019-01-18', '2019-02-15', '2019-03-15', '2019-04-19',\n",
       "               '2019-05-17', '2019-06-21', '2019-07-19', '2019-08-16',\n",
       "               '2019-09-20', '2019-10-18', '2019-11-15', '2019-12-20'],\n",
       "              dtype='datetime64[ns]', freq='WOM-3FRI')"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#WOM（Week Of Month）日期是一种非常实用的频率类\n",
    "#例如2019年每月第三个星期五\n",
    "pd.date_range(start='1/1/2019',periods=12,freq='WOM-3FRI')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 时移 Shift"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "常见的特定于时间序列的操作是数据在时间上的转移。\n",
    "移动（shifting）指的是沿着时间轴将数据前移或后移。\n",
    "pandas有两种密切相关的计算方法：shift()和tshift()。Series和Dataframe都有一个shift()和tshift()方法。\n",
    "简而言之，他们之间的区别是shift() 移动数据，tshift()移动索引..在这两种情况下，移位都是以频率的倍数指定的。\n",
    "df.shift(periods=1, freq=None, axis=0)\n",
    "period：表示移动的幅度 \n",
    "freq： 可选参数，默认值为None，只适用于时间序列，如果这个参数存在，那么会按照参数值移动时间索引，而数据值没有发生变化。 \n",
    "axis： 轴向。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2000-01-31   -1.365959\n",
      "2000-02-29    1.445598\n",
      "2000-03-31   -0.953769\n",
      "2000-04-30    1.323299\n",
      "Freq: M, dtype: float64 \n",
      "\n",
      "正向移动两位数据:\n",
      " 2000-01-31         NaN\n",
      "2000-02-29         NaN\n",
      "2000-03-31   -1.365959\n",
      "2000-04-30    1.445598\n",
      "Freq: M, dtype: float64 \n",
      "\n",
      "反向移动两位数据:\n",
      " 2000-01-31   -0.953769\n",
      "2000-02-29    1.323299\n",
      "2000-03-31         NaN\n",
      "2000-04-30         NaN\n",
      "Freq: M, dtype: float64 \n",
      "\n",
      "相比上月百分比的变化:\n",
      " 2000-01-31         NaN\n",
      "2000-02-29   -1.058303\n",
      "2000-03-31   -0.659775\n",
      "2000-04-30   -1.387443\n",
      "Freq: M, dtype: float64 \n",
      "\n",
      "输入频率实现对时间戳位移:\n",
      " 2000-03-31   -1.365959\n",
      "2000-04-30    1.445598\n",
      "2000-05-31   -0.953769\n",
      "2000-06-30    1.323299\n",
      "Freq: M, dtype: float64 \n",
      "\n"
     ]
    }
   ],
   "source": [
    "#shift\n",
    "ts = pd.Series(np.random.randn(4),index=pd.date_range('1/1/2000',periods=4,freq='m'))\n",
    "print(ts,'\\n')\n",
    "print(\"正向移动两位数据:\\n\",ts.shift(2),'\\n')\n",
    "print(\"反向移动两位数据:\\n\",ts.shift(-2),'\\n')\n",
    "#shift通常用于计算一个时间序列或多个时间序列（如DataFrame的列）中的百分比变化。\n",
    "print(\"相比上月百分比的变化:\\n\",ts/ts.shift(1),'\\n')\n",
    "#由于单纯的移位操作不会修改索引，所以部分数据会被丢弃。如果频率已知，则可以将其传给shift以便实现对时间戳进行位移而不是对数据进行简单位移\n",
    "print(\"输入频率实现对时间戳位移:\\n\",ts.shift(2,freq='M'),'\\n')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(Timestamp('2019-08-22 00:00:00'),\n",
       " Timestamp('2019-08-31 00:00:00'),\n",
       " Timestamp('2019-09-30 00:00:00'))"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#pandas的日期偏移量还可以用在datetime或Timesstamp上\n",
    "from pandas.tseries.offsets import Day,MonthEnd\n",
    "now = datetime(2019,8,19)\n",
    "now+3*Day(),now+MonthEnd(),now+MonthEnd(2)#如果加的是锚点偏移量（比如MonthEnd），第一次增量会将原日期滚动到符合频率规则的下个日期"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(datetime.datetime(2019, 8, 19, 0, 0),\n",
       " Timestamp('2019-08-31 00:00:00'),\n",
       " Timestamp('2019-07-31 00:00:00'))"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#通过锚点偏移量的rollforward和rollback方法，可显式将日期向前或向后滚动\n",
    "offset=MonthEnd()\n",
    "now,offset.rollforward(now),offset.rollback(now)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 六、重采样及频率转换\n",
    "涌采样（resampling）指的是将时间序列从一个频率转换到另一个频率的处理过程。将高频率数据聚合到低频率称为降采样（downsampling），而将低频率数据转换到高频率则称为升采样（upsampling）。本部分我们主要介绍降采样和升采样。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## resample方法"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "pandas对象都有一个resample方法，它是重采样以及各种频率转换工作的主力函数。\n",
    "resample(freq,how='mean',axis=0,fill_method=None,closed='right',label='right',loffset=None,limit=None,convention=None)\n",
    "参数说明\n",
    "freq           表示重采样频率的字符串或DateOffset，例如“M’、‘5min'或Second（15）\n",
    "how='mean'       用于产生聚合值的函数名或数组函数。默认为‘mean'。其他常用的值有：‘first'、last'、‘median'、‘ohlc'、‘max'、'min'\n",
    "axis=0          重采样的轴，默认为axis=0\n",
    "fill_method=None   升采样时如何插值，比如“ffill或“bfill'。默认不插值\n",
    "closed='right'     在降采样中，各时间段的哪一端是闭合（即包含）的，‘right'或left'。默认为right'\n",
    "label='right'     在降采样中，如何设置聚合值的标签，right'或left'（面元的右边界或左边界）。\n",
    "loffset=None      面元标签的时间校正值，比如-1s'/Second（-1）用于将聚合标签调早1秒\n",
    "limit=None       在前向或后向填充时，允许填充的最大时期数kind=None聚合到时期或时间戳，默认聚合到时间序列的索引类型\n",
    "convention=None    当重采样时期时，将低频率转换到高频率所采用的约定（“start'或end’）。默认为end'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2000-01-02    0.235419\n",
       "2000-01-05    2.024163\n",
       "2000-01-07   -0.374881\n",
       "2000-01-08   -1.159212\n",
       "2000-01-10    0.232465\n",
       "2000-01-12    0.636269\n",
       "dtype: float64"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dates = pd.DatetimeIndex(['1/2/2000','1/5/2000','1/7/2000','1/8/2000','1/10/2000','1/12/2000'])\n",
    "ts = pd.Series(np.random.randn(6),index=dates)\n",
    "ts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2000-01-02    0.235419\n",
       "2000-01-03         NaN\n",
       "2000-01-04         NaN\n",
       "2000-01-05    2.024163\n",
       "2000-01-06         NaN\n",
       "2000-01-07   -0.374881\n",
       "2000-01-08   -1.159212\n",
       "2000-01-09         NaN\n",
       "2000-01-10    0.232465\n",
       "2000-01-11         NaN\n",
       "2000-01-12    0.636269\n",
       "Freq: D, dtype: float64"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#利用resample构造完整序列\n",
    "a=ts.resample('D').asfreq()\n",
    "a"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "金融领域中有一种无所不在的时间序列聚合方式，即计算各面元的四个值：第一个值（open，开盘）、最后一个值（close，收盘）、最大值（high，最高）以及最小值（low，最低）。\n",
    "传入how='ohlc’即可得到一个含有这四种聚合值的DataFrame。整个过程很高效，只需一次扫描即可计算出结果："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:2: FutureWarning: how in .resample() is deprecated\n",
      "the new syntax is .resample(...).ohlc()\n",
      "  \n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>open</th>\n",
       "      <th>high</th>\n",
       "      <th>low</th>\n",
       "      <th>close</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2000-01-02 00:00:00</th>\n",
       "      <td>0.235419</td>\n",
       "      <td>0.235419</td>\n",
       "      <td>0.235419</td>\n",
       "      <td>0.235419</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 00:05:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 00:10:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 00:15:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 00:20:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 00:25:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 00:30:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 00:35:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 00:40:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 00:45:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 00:50:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 00:55:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 01:00:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 01:05:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 01:10:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 01:15:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 01:20:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 01:25:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 01:30:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 01:35:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 01:40:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 01:45:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 01:50:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 01:55:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 02:00:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 02:05:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 02:10:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 02:15:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 02:20:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-02 02:25:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 21:35:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 21:40:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 21:45:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 21:50:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 21:55:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 22:00:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 22:05:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 22:10:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 22:15:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 22:20:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 22:25:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 22:30:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 22:35:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 22:40:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 22:45:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 22:50:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 22:55:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 23:00:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 23:05:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 23:10:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 23:15:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 23:20:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 23:25:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 23:30:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 23:35:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 23:40:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 23:45:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 23:50:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11 23:55:00</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-12 00:00:00</th>\n",
       "      <td>0.636269</td>\n",
       "      <td>0.636269</td>\n",
       "      <td>0.636269</td>\n",
       "      <td>0.636269</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>2881 rows × 4 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                         open      high       low     close\n",
       "2000-01-02 00:00:00  0.235419  0.235419  0.235419  0.235419\n",
       "2000-01-02 00:05:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 00:10:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 00:15:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 00:20:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 00:25:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 00:30:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 00:35:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 00:40:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 00:45:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 00:50:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 00:55:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 01:00:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 01:05:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 01:10:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 01:15:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 01:20:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 01:25:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 01:30:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 01:35:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 01:40:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 01:45:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 01:50:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 01:55:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 02:00:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 02:05:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 02:10:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 02:15:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 02:20:00       NaN       NaN       NaN       NaN\n",
       "2000-01-02 02:25:00       NaN       NaN       NaN       NaN\n",
       "...                       ...       ...       ...       ...\n",
       "2000-01-11 21:35:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 21:40:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 21:45:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 21:50:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 21:55:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 22:00:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 22:05:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 22:10:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 22:15:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 22:20:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 22:25:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 22:30:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 22:35:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 22:40:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 22:45:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 22:50:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 22:55:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 23:00:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 23:05:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 23:10:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 23:15:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 23:20:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 23:25:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 23:30:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 23:35:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 23:40:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 23:45:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 23:50:00       NaN       NaN       NaN       NaN\n",
       "2000-01-11 23:55:00       NaN       NaN       NaN       NaN\n",
       "2000-01-12 00:00:00  0.636269  0.636269  0.636269  0.636269\n",
       "\n",
       "[2881 rows x 4 columns]"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#OHLC重采样，统计开盘，最高，最低以及收盘\n",
    "ts.resample('5min',how='ohlc')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 降采样"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "将数据聚合到规整的低频率是一件非常普通的时间序列处理任务。待聚合的数据不必拥有固定的频率，期望的频率会自动定义聚合的面元边界，这些面元用于将时间序列拆分为多个片段。例如，要转换到月度频率（M'或‘BM），数据需要被划分到多个单月时间段中。各时间段都是半开放的。一个数据点只能属于一个时间段，所有时间段的并集必须能组成整个时间帧。在用resample对数据进行降采样时，需要考虑两样东西：\n",
    "·各区间哪边是闭合的。\n",
    "·如何标记各个聚合面元，用区间的开头还是末尾。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2019-01-01 00:00:00     0\n",
       "2019-01-01 00:01:00     1\n",
       "2019-01-01 00:02:00     2\n",
       "2019-01-01 00:03:00     3\n",
       "2019-01-01 00:04:00     4\n",
       "2019-01-01 00:05:00     5\n",
       "2019-01-01 00:06:00     6\n",
       "2019-01-01 00:07:00     7\n",
       "2019-01-01 00:08:00     8\n",
       "2019-01-01 00:09:00     9\n",
       "2019-01-01 00:10:00    10\n",
       "2019-01-01 00:11:00    11\n",
       "Freq: T, dtype: int32"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rng = pd.date_range('1/1/2019',periods=12,freq='T')\n",
    "ts = pd.Series(np.arange(12),index=rng)\n",
    "ts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:2: FutureWarning: how in .resample() is deprecated\n",
      "the new syntax is .resample(...).sum()\n",
      "  \n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "2019-01-01 00:00:00    10\n",
       "2019-01-01 00:05:00    35\n",
       "2019-01-01 00:10:00    21\n",
       "Freq: 5T, dtype: int32"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#通过求和的方式将这些数据聚合到“5分钟”中\n",
    "ts.resample('5min',how='sum')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:4: FutureWarning: how in .resample() is deprecated\n",
      "the new syntax is .resample(...).sum()\n",
      "  after removing the cwd from sys.path.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "2018-12-31 23:55:00     0\n",
       "2019-01-01 00:00:00    15\n",
       "2019-01-01 00:05:00    40\n",
       "2019-01-01 00:10:00    11\n",
       "Freq: 5T, dtype: int32"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#传入的频率将会以“5分钟”的增量定义面元边界。\n",
    "#默认情况下，面元的右边界是包含的，因此00：00到00：05的区间中是包含00：05的1。\n",
    "#选择包含右边界，不包含左边界\n",
    "ts.resample('5min',how='sum',closed='right')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:2: FutureWarning: how in .resample() is deprecated\n",
      "the new syntax is .resample(...).sum()\n",
      "  \n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "2019-01-01 00:05:00    10\n",
       "2019-01-01 00:10:00    35\n",
       "2019-01-01 00:15:00    21\n",
       "Freq: 5T, dtype: int32"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#选择左边界，右边界作为标签\n",
    "ts.resample('5min',how='sum',closed='left',label='right')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:2: FutureWarning: how in .resample() is deprecated\n",
      "the new syntax is .resample(...).sum()\n",
      "  \n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "2018-12-31 23:59:59    10\n",
       "2019-01-01 00:04:59    35\n",
       "2019-01-01 00:09:59    21\n",
       "Freq: 5T, dtype: int32"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#如果你希望对结果索引进行位移，可以使用loffser\n",
    "ts.resample('5min',how='sum',loffset='-1s')"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "另一种降采样的办法是使用pandas的groupby功能。例如，你打算根据月份或星期几进行分组，只需传入一个能够访问时间序列的索引上的这些字段的函数即可："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1    15\n",
       "2    45\n",
       "3    75\n",
       "4    95\n",
       "dtype: int32"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#通过groupby功能实现降采样\n",
    "rng = pd.date_range('1/1/2000',periods=100,freq='D')\n",
    "ts = pd.Series(np.arange(100),index=rng)\n",
    "ts.groupby(lambda x:x.month).mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    47.5\n",
       "1    48.5\n",
       "2    49.5\n",
       "3    50.5\n",
       "4    51.5\n",
       "5    49.0\n",
       "6    50.0\n",
       "dtype: float64"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts.groupby(lambda x:x.weekday).mean()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 升采样和插值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Colorado</th>\n",
       "      <th>Texas</th>\n",
       "      <th>New York</th>\n",
       "      <th>Ohio</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2000-01-05</th>\n",
       "      <td>-0.116549</td>\n",
       "      <td>-0.586241</td>\n",
       "      <td>0.535678</td>\n",
       "      <td>0.908759</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-12</th>\n",
       "      <td>0.900270</td>\n",
       "      <td>1.486212</td>\n",
       "      <td>-0.025083</td>\n",
       "      <td>0.473045</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            Colorado     Texas  New York      Ohio\n",
       "2000-01-05 -0.116549 -0.586241  0.535678  0.908759\n",
       "2000-01-12  0.900270  1.486212 -0.025083  0.473045"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "frame = pd.DataFrame(np.random.randn(2,4),\n",
    "                     index = pd.date_range('1/1/2000',periods=2,freq='W-Wed'),\n",
    "                    columns=['Colorado','Texas','New York','Ohio'])\n",
    "frame"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Colorado</th>\n",
       "      <th>Texas</th>\n",
       "      <th>New York</th>\n",
       "      <th>Ohio</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2000-01-05</th>\n",
       "      <td>-0.116549</td>\n",
       "      <td>-0.586241</td>\n",
       "      <td>0.535678</td>\n",
       "      <td>0.908759</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-06</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-07</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-08</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-09</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-10</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-12</th>\n",
       "      <td>0.900270</td>\n",
       "      <td>1.486212</td>\n",
       "      <td>-0.025083</td>\n",
       "      <td>0.473045</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            Colorado     Texas  New York      Ohio\n",
       "2000-01-05 -0.116549 -0.586241  0.535678  0.908759\n",
       "2000-01-06       NaN       NaN       NaN       NaN\n",
       "2000-01-07       NaN       NaN       NaN       NaN\n",
       "2000-01-08       NaN       NaN       NaN       NaN\n",
       "2000-01-09       NaN       NaN       NaN       NaN\n",
       "2000-01-10       NaN       NaN       NaN       NaN\n",
       "2000-01-11       NaN       NaN       NaN       NaN\n",
       "2000-01-12  0.900270  1.486212 -0.025083  0.473045"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#将其重采样到日频率，默认引入缺失值\n",
    "#新版本需要加上asfreq()获取值\n",
    "#m默认会引入缺失值\n",
    "df_daily = frame.resample('D').asfreq()\n",
    "df_daily"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:2: FutureWarning: fill_method is deprecated to .resample()\n",
      "the new syntax is .resample(...).ffill()\n",
      "  \n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Colorado</th>\n",
       "      <th>Texas</th>\n",
       "      <th>New York</th>\n",
       "      <th>Ohio</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2000-01-05</th>\n",
       "      <td>-0.116549</td>\n",
       "      <td>-0.586241</td>\n",
       "      <td>0.535678</td>\n",
       "      <td>0.908759</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-06</th>\n",
       "      <td>-0.116549</td>\n",
       "      <td>-0.586241</td>\n",
       "      <td>0.535678</td>\n",
       "      <td>0.908759</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-07</th>\n",
       "      <td>-0.116549</td>\n",
       "      <td>-0.586241</td>\n",
       "      <td>0.535678</td>\n",
       "      <td>0.908759</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-08</th>\n",
       "      <td>-0.116549</td>\n",
       "      <td>-0.586241</td>\n",
       "      <td>0.535678</td>\n",
       "      <td>0.908759</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-09</th>\n",
       "      <td>-0.116549</td>\n",
       "      <td>-0.586241</td>\n",
       "      <td>0.535678</td>\n",
       "      <td>0.908759</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-10</th>\n",
       "      <td>-0.116549</td>\n",
       "      <td>-0.586241</td>\n",
       "      <td>0.535678</td>\n",
       "      <td>0.908759</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11</th>\n",
       "      <td>-0.116549</td>\n",
       "      <td>-0.586241</td>\n",
       "      <td>0.535678</td>\n",
       "      <td>0.908759</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-12</th>\n",
       "      <td>0.900270</td>\n",
       "      <td>1.486212</td>\n",
       "      <td>-0.025083</td>\n",
       "      <td>0.473045</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            Colorado     Texas  New York      Ohio\n",
       "2000-01-05 -0.116549 -0.586241  0.535678  0.908759\n",
       "2000-01-06 -0.116549 -0.586241  0.535678  0.908759\n",
       "2000-01-07 -0.116549 -0.586241  0.535678  0.908759\n",
       "2000-01-08 -0.116549 -0.586241  0.535678  0.908759\n",
       "2000-01-09 -0.116549 -0.586241  0.535678  0.908759\n",
       "2000-01-10 -0.116549 -0.586241  0.535678  0.908759\n",
       "2000-01-11 -0.116549 -0.586241  0.535678  0.908759\n",
       "2000-01-12  0.900270  1.486212 -0.025083  0.473045"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#也可以使用前面的周型值进行填充\n",
    "frame.resample('D',fill_method='ffill').asfreq('D')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:2: FutureWarning: fill_method is deprecated to .resample()\n",
      "the new syntax is .resample(...).ffill(limit=2)\n",
      "  \n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Colorado</th>\n",
       "      <th>Texas</th>\n",
       "      <th>New York</th>\n",
       "      <th>Ohio</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2000-01-05</th>\n",
       "      <td>-0.116549</td>\n",
       "      <td>-0.586241</td>\n",
       "      <td>0.535678</td>\n",
       "      <td>0.908759</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-06</th>\n",
       "      <td>-0.116549</td>\n",
       "      <td>-0.586241</td>\n",
       "      <td>0.535678</td>\n",
       "      <td>0.908759</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-07</th>\n",
       "      <td>-0.116549</td>\n",
       "      <td>-0.586241</td>\n",
       "      <td>0.535678</td>\n",
       "      <td>0.908759</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-08</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-09</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-10</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-11</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-01-12</th>\n",
       "      <td>0.900270</td>\n",
       "      <td>1.486212</td>\n",
       "      <td>-0.025083</td>\n",
       "      <td>0.473045</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            Colorado     Texas  New York      Ohio\n",
       "2000-01-05 -0.116549 -0.586241  0.535678  0.908759\n",
       "2000-01-06 -0.116549 -0.586241  0.535678  0.908759\n",
       "2000-01-07 -0.116549 -0.586241  0.535678  0.908759\n",
       "2000-01-08       NaN       NaN       NaN       NaN\n",
       "2000-01-09       NaN       NaN       NaN       NaN\n",
       "2000-01-10       NaN       NaN       NaN       NaN\n",
       "2000-01-11       NaN       NaN       NaN       NaN\n",
       "2000-01-12  0.900270  1.486212 -0.025083  0.473045"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#限制填充期数\n",
    "frame.resample('D',fill_method='ffill',limit=2).asfreq('D')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 通过时期进行重采样"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "由于时期指的是时间区间，所以升采样和降采样的规则就比较严格：\n",
    "·在降采样中，目标频率必须是源频率的子时期（subperiod）。\n",
    "·在升采样中，目标频率必须是源频率的超时期（superperiod）。\n",
    "如果不满足这些条件，就会引发异常。这主要影响的是按季、年、周计算的频率。例如，由Q-MAR定义的时间区间只能升采样为A-MAR、A-JUN、A-SEP、A-DEC等："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Colorado</th>\n",
       "      <th>Texas</th>\n",
       "      <th>New York</th>\n",
       "      <th>Ohio</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2000-01</th>\n",
       "      <td>-1.360795</td>\n",
       "      <td>0.829555</td>\n",
       "      <td>-0.596584</td>\n",
       "      <td>0.791686</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-02</th>\n",
       "      <td>-1.346094</td>\n",
       "      <td>0.120454</td>\n",
       "      <td>-1.179666</td>\n",
       "      <td>-1.021255</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-03</th>\n",
       "      <td>-1.557079</td>\n",
       "      <td>0.815604</td>\n",
       "      <td>-1.154167</td>\n",
       "      <td>-1.200424</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-04</th>\n",
       "      <td>-1.727358</td>\n",
       "      <td>0.022920</td>\n",
       "      <td>0.633838</td>\n",
       "      <td>0.590345</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-05</th>\n",
       "      <td>-1.978317</td>\n",
       "      <td>0.397222</td>\n",
       "      <td>-0.384799</td>\n",
       "      <td>-0.978572</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         Colorado     Texas  New York      Ohio\n",
       "2000-01 -1.360795  0.829555 -0.596584  0.791686\n",
       "2000-02 -1.346094  0.120454 -1.179666 -1.021255\n",
       "2000-03 -1.557079  0.815604 -1.154167 -1.200424\n",
       "2000-04 -1.727358  0.022920  0.633838  0.590345\n",
       "2000-05 -1.978317  0.397222 -0.384799 -0.978572"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "frame = pd.DataFrame(np.random.randn(24,4),\n",
    "                     index = pd.period_range('1-2000','12-2001',freq='M'),\n",
    "                    columns=['Colorado','Texas','New York','Ohio'])\n",
    "frame[:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:2: FutureWarning: how in .resample() is deprecated\n",
      "the new syntax is .resample(...).mean()\n",
      "  \n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Colorado</th>\n",
       "      <th>Texas</th>\n",
       "      <th>New York</th>\n",
       "      <th>Ohio</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2000</th>\n",
       "      <td>-0.690458</td>\n",
       "      <td>-0.215923</td>\n",
       "      <td>-0.161279</td>\n",
       "      <td>0.237725</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2001</th>\n",
       "      <td>-0.036384</td>\n",
       "      <td>-0.045400</td>\n",
       "      <td>-0.221312</td>\n",
       "      <td>0.090525</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      Colorado     Texas  New York      Ohio\n",
       "2000 -0.690458 -0.215923 -0.161279  0.237725\n",
       "2001 -0.036384 -0.045400 -0.221312  0.090525"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#降采样\n",
    "annual_frame = frame.resample('A-DEC',how='mean')\n",
    "annual_frame"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:4: FutureWarning: fill_method is deprecated to .resample()\n",
      "the new syntax is .resample(...).ffill()\n",
      "  after removing the cwd from sys.path.\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Colorado</th>\n",
       "      <th>Texas</th>\n",
       "      <th>New York</th>\n",
       "      <th>Ohio</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2000Q1</th>\n",
       "      <td>-0.690458</td>\n",
       "      <td>-0.215923</td>\n",
       "      <td>-0.161279</td>\n",
       "      <td>0.237725</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000Q2</th>\n",
       "      <td>-0.690458</td>\n",
       "      <td>-0.215923</td>\n",
       "      <td>-0.161279</td>\n",
       "      <td>0.237725</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000Q3</th>\n",
       "      <td>-0.690458</td>\n",
       "      <td>-0.215923</td>\n",
       "      <td>-0.161279</td>\n",
       "      <td>0.237725</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000Q4</th>\n",
       "      <td>-0.690458</td>\n",
       "      <td>-0.215923</td>\n",
       "      <td>-0.161279</td>\n",
       "      <td>0.237725</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2001Q1</th>\n",
       "      <td>-0.036384</td>\n",
       "      <td>-0.045400</td>\n",
       "      <td>-0.221312</td>\n",
       "      <td>0.090525</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2001Q2</th>\n",
       "      <td>-0.036384</td>\n",
       "      <td>-0.045400</td>\n",
       "      <td>-0.221312</td>\n",
       "      <td>0.090525</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2001Q3</th>\n",
       "      <td>-0.036384</td>\n",
       "      <td>-0.045400</td>\n",
       "      <td>-0.221312</td>\n",
       "      <td>0.090525</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2001Q4</th>\n",
       "      <td>-0.036384</td>\n",
       "      <td>-0.045400</td>\n",
       "      <td>-0.221312</td>\n",
       "      <td>0.090525</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        Colorado     Texas  New York      Ohio\n",
       "2000Q1 -0.690458 -0.215923 -0.161279  0.237725\n",
       "2000Q2 -0.690458 -0.215923 -0.161279  0.237725\n",
       "2000Q3 -0.690458 -0.215923 -0.161279  0.237725\n",
       "2000Q4 -0.690458 -0.215923 -0.161279  0.237725\n",
       "2001Q1 -0.036384 -0.045400 -0.221312  0.090525\n",
       "2001Q2 -0.036384 -0.045400 -0.221312  0.090525\n",
       "2001Q3 -0.036384 -0.045400 -0.221312  0.090525\n",
       "2001Q4 -0.036384 -0.045400 -0.221312  0.090525"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#升采样稍微麻烦，因为需要决定在新的频率各区间的哪端用于放置原来的值\n",
    "#convention参数默认为start，可设置为end\n",
    "#重新把年的汇总转为为季度型：Q-DEC，季度型，每年以12月结束\n",
    "annual_frame.resample('Q-DEC',fill_method='ffill')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:1: FutureWarning: fill_method is deprecated to .resample()\n",
      "the new syntax is .resample(...).ffill()\n",
      "  \"\"\"Entry point for launching an IPython kernel.\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Colorado</th>\n",
       "      <th>Texas</th>\n",
       "      <th>New York</th>\n",
       "      <th>Ohio</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2000Q4</th>\n",
       "      <td>-0.690458</td>\n",
       "      <td>-0.215923</td>\n",
       "      <td>-0.161279</td>\n",
       "      <td>0.237725</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2001Q1</th>\n",
       "      <td>-0.690458</td>\n",
       "      <td>-0.215923</td>\n",
       "      <td>-0.161279</td>\n",
       "      <td>0.237725</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2001Q2</th>\n",
       "      <td>-0.690458</td>\n",
       "      <td>-0.215923</td>\n",
       "      <td>-0.161279</td>\n",
       "      <td>0.237725</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2001Q3</th>\n",
       "      <td>-0.690458</td>\n",
       "      <td>-0.215923</td>\n",
       "      <td>-0.161279</td>\n",
       "      <td>0.237725</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2001Q4</th>\n",
       "      <td>-0.036384</td>\n",
       "      <td>-0.045400</td>\n",
       "      <td>-0.221312</td>\n",
       "      <td>0.090525</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        Colorado     Texas  New York      Ohio\n",
       "2000Q4 -0.690458 -0.215923 -0.161279  0.237725\n",
       "2001Q1 -0.690458 -0.215923 -0.161279  0.237725\n",
       "2001Q2 -0.690458 -0.215923 -0.161279  0.237725\n",
       "2001Q3 -0.690458 -0.215923 -0.161279  0.237725\n",
       "2001Q4 -0.036384 -0.045400 -0.221312  0.090525"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "annual_frame.resample('Q-DEC',fill_method='ffill',convention='end')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 七、移动窗囗函数\n",
    "在移动窗口（可以带有指数衰减权数）上计算的各种统计函数也是一类常见于时间序列的数组变换。我将它们称为移动窗口函数（moving window function），其中还包括那些窗口不定长的函数（如指数加权移动平均）。跟其他统计函数一样，移动窗口函数也会自动排除缺失值。"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "DataFrame.rolling(window, min_periods=None, center=False, win_type=None, on=None, axis=0, closed=None)\n",
    "window      时间窗大小\n",
    "min_periods 每个窗口最少包含的观测数量\n",
    "center      窗口的标签设置为居中\n",
    "win_type    窗口的类型\n",
    "on          可选参数，指定要计算的列名\n",
    "axis        轴向\n",
    "closed      定义区间的开闭"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2019-01-16     4\n",
       "2019-01-17     8\n",
       "2019-01-18     6\n",
       "2019-01-19     5\n",
       "2019-01-20     9\n",
       "2019-01-21     1\n",
       "2019-01-22     4\n",
       "2019-01-23     5\n",
       "2019-01-24     2\n",
       "2019-01-25     4\n",
       "2019-01-26     6\n",
       "2019-01-27     7\n",
       "2019-01-28     9\n",
       "2019-01-29    13\n",
       "2019-01-30     6\n",
       "Freq: D, dtype: int64"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "index=pd.date_range('20190116','20190130')\n",
    "data=[4,8,6,5,9,1,4,5,2,4,6,7,9,13,6]\n",
    "ser_data=pd.Series(data,index=index)\n",
    "ser_data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2019-01-16         NaN\n",
       "2019-01-17         NaN\n",
       "2019-01-18    6.000000\n",
       "2019-01-19    6.333333\n",
       "2019-01-20    6.666667\n",
       "2019-01-21    5.000000\n",
       "2019-01-22    4.666667\n",
       "2019-01-23    3.333333\n",
       "2019-01-24    3.666667\n",
       "2019-01-25    3.666667\n",
       "2019-01-26    4.000000\n",
       "2019-01-27    5.666667\n",
       "2019-01-28    7.333333\n",
       "2019-01-29    9.666667\n",
       "2019-01-30    9.333333\n",
       "Freq: D, dtype: float64"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ser_data.rolling(3).mean()"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "当窗口开始滑动时，第一个时间点和第二个时间点的时间为空，这是因为这里窗口长度为3，他们前面的数都不够3，所以到2019-01-18时，他的数据就是2019-01-16到2019-01-18三天的均值。\n",
    "那么，在计算2019-01-16序列的窗口数据时，虽然不够窗口长度3，但是至少有当天的数据，那么能否就用当天的数据代表窗口数据呢？答案是肯定的，这里我们可以通过min_periods参数控制，表示窗口最少包含的观测值，小于这个值的窗口长度显示为空，等于和大于时有值，如下所示："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2019-01-16    4.000000\n",
       "2019-01-17    6.000000\n",
       "2019-01-18    6.000000\n",
       "2019-01-19    6.333333\n",
       "2019-01-20    6.666667\n",
       "2019-01-21    5.000000\n",
       "2019-01-22    4.666667\n",
       "2019-01-23    3.333333\n",
       "2019-01-24    3.666667\n",
       "2019-01-25    3.666667\n",
       "2019-01-26    4.000000\n",
       "2019-01-27    5.666667\n",
       "2019-01-28    7.333333\n",
       "2019-01-29    9.666667\n",
       "2019-01-30    9.333333\n",
       "Freq: D, dtype: float64"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ser_data.rolling(3,min_periods=1).mean()#表示窗口最少包含的观测值为1"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "除此之外，还有一些其它的rolling函数，均是以rolling为前缀的函数\n",
    "rolling_count返回各窗口非NA观测值的数量\n",
    "rolling_sum移动窗口的和\n",
    "rolling_mean移动窗口的平均值\n",
    "rolling_median移动窗口的中位数\n",
    "rolling_var、rolling_std移动窗口的方差和标准差。分母为n-1\n",
    "rolling_skew、olling_kurt移动窗口的偏度（三阶矩）和峰度（四阶矩）\n",
    "rolling_min、rolling_max移动窗口的最小值和最大值\n",
    "rolling_quantile移动窗口指定百分位数/样本分位数位置的值\n",
    "rolling_cor、rolling_cov移动窗口的相关系数和协方差\n",
    "rolling_apply对移动窗口应用普通数组函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "各窗口非NA观测值的数量: 2019-01-16    1.0\n",
      "2019-01-17    2.0\n",
      "2019-01-18    3.0\n",
      "2019-01-19    3.0\n",
      "2019-01-20    3.0\n",
      "2019-01-21    3.0\n",
      "2019-01-22    3.0\n",
      "2019-01-23    3.0\n",
      "2019-01-24    3.0\n",
      "2019-01-25    3.0\n",
      "2019-01-26    3.0\n",
      "2019-01-27    3.0\n",
      "2019-01-28    3.0\n",
      "2019-01-29    3.0\n",
      "2019-01-30    3.0\n",
      "Freq: D, dtype: float64\n",
      "移动窗口的和: 2019-01-16     NaN\n",
      "2019-01-17     NaN\n",
      "2019-01-18    18.0\n",
      "2019-01-19    19.0\n",
      "2019-01-20    20.0\n",
      "2019-01-21    15.0\n",
      "2019-01-22    14.0\n",
      "2019-01-23    10.0\n",
      "2019-01-24    11.0\n",
      "2019-01-25    11.0\n",
      "2019-01-26    12.0\n",
      "2019-01-27    17.0\n",
      "2019-01-28    22.0\n",
      "2019-01-29    29.0\n",
      "2019-01-30    28.0\n",
      "Freq: D, dtype: float64\n",
      "移动窗口的平均值: 2019-01-16         NaN\n",
      "2019-01-17         NaN\n",
      "2019-01-18    6.000000\n",
      "2019-01-19    6.333333\n",
      "2019-01-20    6.666667\n",
      "2019-01-21    5.000000\n",
      "2019-01-22    4.666667\n",
      "2019-01-23    3.333333\n",
      "2019-01-24    3.666667\n",
      "2019-01-25    3.666667\n",
      "2019-01-26    4.000000\n",
      "2019-01-27    5.666667\n",
      "2019-01-28    7.333333\n",
      "2019-01-29    9.666667\n",
      "2019-01-30    9.333333\n",
      "Freq: D, dtype: float64\n",
      "移动窗口的中位数: 2019-01-16    NaN\n",
      "2019-01-17    NaN\n",
      "2019-01-18    6.0\n",
      "2019-01-19    6.0\n",
      "2019-01-20    6.0\n",
      "2019-01-21    5.0\n",
      "2019-01-22    4.0\n",
      "2019-01-23    4.0\n",
      "2019-01-24    4.0\n",
      "2019-01-25    4.0\n",
      "2019-01-26    4.0\n",
      "2019-01-27    6.0\n",
      "2019-01-28    7.0\n",
      "2019-01-29    9.0\n",
      "2019-01-30    9.0\n",
      "Freq: D, dtype: float64\n",
      "移动窗口的方差: 2019-01-16          NaN\n",
      "2019-01-17          NaN\n",
      "2019-01-18     4.000000\n",
      "2019-01-19     2.333333\n",
      "2019-01-20     4.333333\n",
      "2019-01-21    16.000000\n",
      "2019-01-22    16.333333\n",
      "2019-01-23     4.333333\n",
      "2019-01-24     2.333333\n",
      "2019-01-25     2.333333\n",
      "2019-01-26     4.000000\n",
      "2019-01-27     2.333333\n",
      "2019-01-28     2.333333\n",
      "2019-01-29     9.333333\n",
      "2019-01-30    12.333333\n",
      "Freq: D, dtype: float64\n",
      "移动窗口的标准差: 2019-01-16         NaN\n",
      "2019-01-17         NaN\n",
      "2019-01-18    2.000000\n",
      "2019-01-19    1.527525\n",
      "2019-01-20    2.081666\n",
      "2019-01-21    4.000000\n",
      "2019-01-22    4.041452\n",
      "2019-01-23    2.081666\n",
      "2019-01-24    1.527525\n",
      "2019-01-25    1.527525\n",
      "2019-01-26    2.000000\n",
      "2019-01-27    1.527525\n",
      "2019-01-28    1.527525\n",
      "2019-01-29    3.055050\n",
      "2019-01-30    3.511885\n",
      "Freq: D, dtype: float64\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:1: FutureWarning: pd.rolling_count is deprecated for Series and will be removed in a future version, replace with \n",
      "\tSeries.rolling(window=3).count()\n",
      "  \"\"\"Entry point for launching an IPython kernel.\n",
      "D:\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:2: FutureWarning: pd.rolling_sum is deprecated for Series and will be removed in a future version, replace with \n",
      "\tSeries.rolling(window=3,center=False).sum()\n",
      "  \n",
      "D:\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:3: FutureWarning: pd.rolling_mean is deprecated for Series and will be removed in a future version, replace with \n",
      "\tSeries.rolling(window=3,center=False).mean()\n",
      "  This is separate from the ipykernel package so we can avoid doing imports until\n",
      "D:\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:4: FutureWarning: pd.rolling_median is deprecated for Series and will be removed in a future version, replace with \n",
      "\tSeries.rolling(window=3,center=False).median()\n",
      "  after removing the cwd from sys.path.\n",
      "D:\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:5: FutureWarning: pd.rolling_var is deprecated for Series and will be removed in a future version, replace with \n",
      "\tSeries.rolling(window=3,center=False).var()\n",
      "  \"\"\"\n",
      "D:\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:6: FutureWarning: pd.rolling_std is deprecated for Series and will be removed in a future version, replace with \n",
      "\tSeries.rolling(window=3,center=False).std()\n",
      "  \n"
     ]
    }
   ],
   "source": [
    "print(\"各窗口非NA观测值的数量:\",pd.rolling_count(ser_data,window = 3))\n",
    "print(\"移动窗口的和:\",pd.rolling_sum(ser_data,window = 3))\n",
    "print(\"移动窗口的平均值:\",pd.rolling_mean(ser_data,window = 3))\n",
    "print(\"移动窗口的中位数:\",pd.rolling_median(ser_data,window = 3))\n",
    "print(\"移动窗口的方差:\",pd.rolling_var(ser_data,window = 3))\n",
    "print(\"移动窗口的标准差:\",pd.rolling_std(ser_data,window = 3))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 八、指数加权函数\n",
    "另一种使用固定大小窗口及相等权数观测值的办法是，定义一个衰减因子常量，以便使近期的观测值拥有更大的权数。 用数学术语来讲，如果ma1是时间t的移动平均结果，x是时间序列，结果中的各个值可用ma1=ama(t-1)+（a-1）x(t-1)进行计算，其中a为衰减因子。 衰减因子的定义方式有很多，比较流行的是使用时间间隔（span），它可以使结果兼容于窗口大小等于时间间隔的简单移动窗口函数。 由于指数加权统计会赋予近期的观测值更大的权数，因此相对于等权统计，它能“适应”更快的变化。"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "ewma(arg,com=None,span=None,halflife=None,min_periods=0,freq=None,adjust =True,how = None,ignore_na = False)指数加权移动平均\n",
    "ewmvar(arg,com=None,span=None,halflife=None,min_periods=0,bias=False,freq=None,how=None,ignore_na=False,adjust=True)指数加权移动方差\n",
    "ewmstd(arg,com=None,span=None,halflife=None,min_periods=0,bias=False,ignore_na=False,adjust=True) 指数加权移动标准差\n",
    "ewmcorr(arg1,arg2=None,com=None,span=None,halflife=None,min_periods=0,freq=None,pairwise=None,how=None,ignore_na=False,adjust=True)指数加权移动相关系数\n",
    "ewmcov(arg1,arg2,com=None,span=None,halflife=None,min_periods=0,bias=False,freq=None) 指数加权移动协方差\n",
    "参数说明\n",
    "arg，arg1，arg2：Series，DataFrame\n",
    "com：质量中心。可选的\n",
    "span：根据跨度指定衰减，可选\n",
    "halflife：根据半衰期指定衰减，可选\n",
    "min_periods：具有值所需的窗口中的最小观察数（否则结果为NA），默认值为0\n",
    "bias：使用标准估计偏差校正，默认为False\n",
    "how：用于下采样或重采样的方法，默认为mean\n",
    "ignore_na：计算权重时忽略缺失值; 指定True以重现0.15.0之前的行为，默认为False\n",
    "freq：在计算统计数据之前要符合的频率，默认=无\n",
    "adjust：除以初期的衰减调整因子，以解释相对权重的不平衡（将EWMA视为移动平均线），默认为True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Anaconda3\\lib\\site-packages\\statsmodels\\compat\\pandas.py:56: FutureWarning: The pandas.core.datetools module is deprecated and will be removed in a future version. Please use the pandas.tseries module instead.\n",
      "  from pandas.core import datetools\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>YEAR</th>\n",
       "      <th>SUNACTIVITY</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1700.0</td>\n",
       "      <td>5.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1701.0</td>\n",
       "      <td>11.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1702.0</td>\n",
       "      <td>16.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1703.0</td>\n",
       "      <td>23.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1704.0</td>\n",
       "      <td>36.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>1705.0</td>\n",
       "      <td>58.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>1706.0</td>\n",
       "      <td>29.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>1707.0</td>\n",
       "      <td>20.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>1708.0</td>\n",
       "      <td>10.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>1709.0</td>\n",
       "      <td>8.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>1710.0</td>\n",
       "      <td>3.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>1711.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>1712.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>1713.0</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>1714.0</td>\n",
       "      <td>11.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      YEAR  SUNACTIVITY\n",
       "0   1700.0          5.0\n",
       "1   1701.0         11.0\n",
       "2   1702.0         16.0\n",
       "3   1703.0         23.0\n",
       "4   1704.0         36.0\n",
       "5   1705.0         58.0\n",
       "6   1706.0         29.0\n",
       "7   1707.0         20.0\n",
       "8   1708.0         10.0\n",
       "9   1709.0          8.0\n",
       "10  1710.0          3.0\n",
       "11  1711.0          0.0\n",
       "12  1712.0          0.0\n",
       "13  1713.0          2.0\n",
       "14  1714.0         11.0"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import statsmodels.api as sm\n",
    "\n",
    "data_loader = sm.datasets.sunspots.load_pandas()\n",
    "df = data_loader.data\n",
    "df.head(15)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "EMA: 0           NaN\n",
      "1           NaN\n",
      "2           NaN\n",
      "3           NaN\n",
      "4           NaN\n",
      "5           NaN\n",
      "6           NaN\n",
      "7           NaN\n",
      "8           NaN\n",
      "9     20.690866\n",
      "10    17.076843\n",
      "11    13.664921\n",
      "12    10.982917\n",
      "13     9.244962\n",
      "14     9.580603\n",
      "Name: SUNACTIVITY, dtype: float64\n"
     ]
    }
   ],
   "source": [
    "print(\"EMA:\",df[\"SUNACTIVITY\"].ewm(span=10,min_periods=10).mean().head(15))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
